package net.scribblemedia.sqldsk.service.init;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import net.scribblemedia.sqldsk.domain.DatabaseConfig;
import net.scribblemedia.sqldsk.domain.DatabaseDriver;
import net.scribblemedia.sqldsk.domain.ReportQuery;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

@Transactional
@Component
public class DataInitialisationService implements ApplicationListener<ContextRefreshedEvent> {

	@Autowired
	private List<DatabaseDriver> databaseDrivers;
	
	@Autowired
	private List<DatabaseConfig> databaseConfigs;
	
	@Autowired
	private List<ReportQuery> reportQueries;
	
    @PersistenceContext
    transient EntityManager entityManager;
	
	@Override
	public void onApplicationEvent(ContextRefreshedEvent event) {
    	if (event.getApplicationContext().getParent() == null) {
    		insertDatabaseDriversIfNecessary();
    		insertDatabaseConfigsIfNecessary();
    		insertReportQueriesIfNecessary();
    	}
	}
	
	@Transactional
	private void insertReportQueriesIfNecessary() {
		for (ReportQuery reportQuery : reportQueries) {
			String databaseConfigName = reportQuery.getDatabaseConfig().getDatabaseConfigName();
			DatabaseConfig persistedDatabaseConfig = DatabaseConfig.findDatabaseConfigsByDatabaseConfigNameEquals(databaseConfigName).getSingleResult();
			if (ReportQuery.findReportQuerysByNameAndDatabaseConfigEquals(reportQuery.getName(), persistedDatabaseConfig).getResultList().isEmpty()) {
				reportQuery.persist();
				persistedDatabaseConfig.addReportQuery(reportQuery);
			}
		}
		
	}

	@Transactional
	private void insertDatabaseConfigsIfNecessary() {
		for (DatabaseConfig databaseConfig : databaseConfigs) {
			if (DatabaseConfig.findDatabaseConfigsByDatabaseConfigNameEquals(databaseConfig.getDatabaseConfigName()).getResultList().isEmpty()) {
				DatabaseDriver databaseDriver = DatabaseDriver.findDatabaseDriversByDriverClassEquals(databaseConfig.getDriver().getDriverClass()).getSingleResult();
				databaseConfig.setDriver(null);
				databaseConfig.persist();
				databaseDriver.addDatabaseConfig(databaseConfig);
			}
		}
	}

	@Transactional
	private void insertDatabaseDriversIfNecessary() {
		for (DatabaseDriver databaseDriver : databaseDrivers) {
			if (databaseDriver != null && DatabaseDriver.findDatabaseDriversByDriverClassEquals(databaseDriver.getDriverClass()).getResultList().isEmpty()) {
				databaseDriver.persist();
			}
		}
	}
}
